<!--
@author ljy
日志：
20220409创建
20240804修改，根据element-plus新版本对checkbox的要求，修改checkbox的标签



查询表单的列选择，用于配合查询表单，控制查询表单的显示。
初始化时默认全部为选中状态。
 一、用法
（一）基本用法（例子参照账户管理模块查询菜单：@/components/base/table/TableQueryFormItemSetting.vue）
1.1 引入组件的方式
import TableQueryFormItemSetting from '@/components/base/table/TableQueryFormItemSetting.vue';
1.2 使用方式
<TableQueryFormItemSetting
          :formHeaders="formHeaders"
          :extraFormHeaders="extraFormHeaders"
          @changeSelect="changeSelect"
        />
1.3 参数说明：
（1）formHeaders，表格的列集合属性
（2）changeColumnSelect(columnsSelected:string[])
当选中的表格列发生变化时触发，参数columnsSelected表示最新的列选择属性
-->

<template>
  <el-popover placement="bottom-end" :width="80" trigger="click" v-if="extraFormHeaders.length > 0">
    <template #reference>
      <el-button icon="Setting" class="button">筛选</el-button>
    </template>
    <!--全选按钮-->
    <el-checkbox label="全选" v-model="allColumnsSelected" @change="handleCheckAllChange" />
    <el-divider style="margin: 4px 0" />
    <el-checkbox-group v-model="columnsSelected">
      <!--查询表单所有选项-->
      <div v-for="item in allFormHeaders" :key="item.prop">
        <el-checkbox :value="item.prop" :label="item.label" />
      </div>
    </el-checkbox-group>
  </el-popover>
</template>

<script lang="ts" setup>
import { ref, defineProps, watch, defineExpose, onMounted, computed, withDefaults, nextTick } from 'vue';
import type { FormHeader } from '@/types/interface/base_interface';
// 导入下载文件函数
// import { download } from '@/api/utils/FileUtil';
import { defineEmits } from 'vue';
const emit = defineEmits(['changeSelect']);
// 读取父容器传递过来的选择列表
interface Props {
  // 需要在父组件引入自定义的@/api/uem/useTableList.ts组件，然后将其中的部分属性传过来
  formHeaders: FormHeader[]; // 初始化的表单元素集合,默认选中
  extraFormHeaders?: FormHeader[]; // 额外的表单元素集合，默认不选中,只有该集合存在才会显示本组件的筛选按钮
}
const props = withDefaults(defineProps<Props>(), {
  extraFormHeaders: () => new Array<FormHeader>()
});
// 将基础查询表单元素和扩展查询表单元素整合，注意是数组形式
const allFormHeaders = ref<FormHeader[]>([]);
// 已经选择的表格列
const columnsSelected = ref<string[]>([]);
//20240819加上，因为可能在个别场景是异步交互的，因此要对异步交互后传过来的值进行处理
watch(
  () => [props.formHeaders, props.extraFormHeaders],
  async (newVal: any, oldVal: any) => {
    //先清空原来表单的初始选中元素
    columnsSelected.value.splice(0, columnsSelected.value.length);
    // 初始化时，默认的元素集合为选中状态
    props.formHeaders.forEach((item: FormHeader) => {
      columnsSelected.value.push(item.prop);
    });
    //
    allFormHeaders.value = JSON.parse(JSON.stringify(props.formHeaders.concat(props.extraFormHeaders)));
    await nextTick();
  },
  { deep: true, immediate: true }
);
// 全选按钮的选中状态
const allColumnsSelected = ref(false);
// 当全选复选框勾选或取消的操作
const handleCheckAllChange = (value: boolean): void => {
  if (value) {
    // 如果全选框为选中状态
    allColumnsSelected.value = true;
    // 先清空已选择列表
    columnsSelected.value = [];
    // 全选所有
    allFormHeaders.value.forEach((formHeader: FormHeader) => {
      columnsSelected.value.push(formHeader.prop);
    });
  } else {
    allColumnsSelected.value = false;
    // 清空已选择列表
    columnsSelected.value = [];
  }
};
// 监控已选择列表，保证全选状态显示的合理性
watch(
  columnsSelected,
  (newVal: any, oldVal: any) => {
    emit('changeSelect', newVal);
    if (newVal.length < allFormHeaders.value.length) {
      // 如果选择的选项少于所有选项，则全选按钮不打钩
      allColumnsSelected.value = false;
    } else {
      allColumnsSelected.value = true;
    }
  },
  { immediate: true, deep: true }
);
</script>

<style lang="scss" scoped>
.button {
  margin: 0 0 0 5px;
}
</style>
